package cn.wgx.modules.base.web;

import cn.wgx.commons.annotation.ApiPermission;
import cn.wgx.commons.util.SMSSender;
import cn.wgx.commons.util.StringUtils;
import cn.wgx.commons.util.ValidateCodeImageUtil;
import cn.wgx.commons.util.Validation;
import cn.wgx.modules.sys.entity.SysUser;
import cn.wgx.modules.sys.services.SysUserService;
import cn.wgx.modules.sys.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;

@Api(description = "短信接口")
@RestController
@RequestMapping(value = "api/sms")
public class SMSController extends BaseController {

    @Resource
    SysUserService sysUserService;

    public final static String SESSION_BING_KEY_DATE = "smssenddate";
    public final static String SESSION_BIND_KEY_PHONE = "bindphonekey";
    public final static String SESSION_BIND_SEND_PHONE = "SESSION_BIND_SEND_PHONE";
    public final static String SESSION_BIND_IS_SMS = "SESSION_BIND_IS_SMS";
    private final static String BIND_PHONE_STRING = "您正在登录中科北影移动办公系统，验证码为：{{code}}，请勿泄漏验证码。如非本人操作，请联系我们010-64128837。【中科北影】";
    private final static String CHANGE_PASS_STRING = "您正在设置登录密码，验证码为：{{code}}。请勿泄漏验证码，唯一热线010-64128837。【中科北影】";
    private final static String BIND_PHONE= "您正在绑定手机号，验证码为：{{code}}。请勿泄漏验证码，唯一热线010-64128837。【中科北影】";

    @ApiOperation("绑定新手机号码发送验证码,需要登录")
    @ApiPermission(value = false)
    @RequestMapping(value = "bindphone/{phone}/{code}", method = RequestMethod.GET)
    public Map<String,Object> sendSMS(@ApiParam("原手机接收验证码") @PathVariable(required = false) String code,
                                      @ApiParam("新绑定手机号码")@PathVariable String phone,
                                      HttpSession session){
        Map<String,Object> map = getInitMap();
        SysUser sysUser = UserUtil.getUser();
        String oldPhone = sysUser.getPhone();
        if(sysUser.getPhoneCheck() && Validation.isMobile(oldPhone)){
            //第二次绑定,验证旧手机验证码
            if(null == code || !ValidateCodeImageUtil.validCode(session, code, map,true)){
                return returnErrorMap("验证码错误", map);
            }else if(!sysUserService.checkPhone(phone)){
                return returnErrorMap("手机号已注册", map);
            }else{
                session.setAttribute(SESSION_BING_KEY_DATE, 0);
                map = sendSmsByType(phone,1,session);
            }
        }else if(!sysUserService.checkPhone(phone)){
            return returnErrorMap("手机号已注册", map);
        }else{
            //第一次绑定
            map = sendSmsByType(phone,1,session);
        }
        return map;
    }


    @ApiOperation("修改手机号码 - 旧手机发送验证码,需要登录")
    @ApiPermission(value = false)
    @RequestMapping(value = "bindphone", method = RequestMethod.GET)
    public Map<String,Object> validPhone(HttpSession session){
        SysUser sysUser = UserUtil.getUser();
        String phone = sysUser.getPhone();
        Map<String,Object> map = getInitMap();
        if(sysUser.getPhoneCheck() && Validation.isMobile(sysUser.getPhone())){
            return sendSmsByType(phone,1,session);
        }
        return returnErrorMap("未绑定手机号码.",map);
    }

    @ApiOperation("找回密码发送验证码,需要手机号码(已绑定的)")
    @RequestMapping(value = "changepass/{phone}", method = RequestMethod.GET)
    public Map<String,Object> changePassSMSByPhone(@PathVariable String phone,
                                            HttpSession session){

        Map<String,Object> map = getInitMap();
        SysUser sysUser = sysUserService.getSysUserByPhone(phone, false);
        if(null != sysUser){
            if(sysUser.getPhoneCheck()){
                return sendSmsByType(phone, 1, session);
            }else{
                returnErrorMap("该用户未绑定手机号码.",map);
            }
        }else{
            returnErrorMap("未知用户或已锁定.",map);
        }
        return map;
    }

    @ApiOperation("找回密码发送验证码,需要用户名")
    @RequestMapping(value = "changepassbyphone/{username}", method = RequestMethod.GET)
    public Map<String,Object> changePassSMS(@ApiParam("用户名")@PathVariable String username,
                                            HttpSession session){

        Map<String,Object> map = getInitMap();
        SysUser sysUser = sysUserService.getSysUserByUsername(username, false, true);
        if(null != sysUser){
            String phone = sysUser.getPhone();
            if(sysUser.getPhoneCheck()){
                return sendSmsByType(phone, 1, session);
            }else{
                returnErrorMap("该用户未绑定手机号码.",map);
            }
        }else{
            returnErrorMap("未知用户或已锁定.",map);
        }
        return map;
    }

    /**
     * 检测验证码正确
     * @param code
     * @param session
     * @return
     *
     */
    @ApiOperation("检测手机验证码是否正确")
    @RequestMapping(value = "checkcode/{code}", method = RequestMethod.GET)
    public Map<String,Object> checkCode(@PathVariable String code,HttpSession session){

        Map<String,Object> map = getInitMap();
        if(!ValidateCodeImageUtil.validCode(session,code,map,false)){
            return returnErrorMap("验证码错误",map);
        }
        return map;

    }

    /**
     * 根据类型发送不同验证码字符
     * @param phone
     * @param type 1为改密,2为绑定
     * @param session
     * @return
     */
    private Map<String,Object> sendSmsByType(String phone,
                                      Integer type,
                                      HttpSession session){
        Map<String,Object> map = getInitMap();
        if(!canSendSMS(session)){
            return returnErrorMap("发送时间间隔过短(1分钟).",map);
        }
        if(Validation.isMobile(phone)){
            String code = StringUtils.getRadomCode();
            String sms;
            if(type == 1){
                sms = CHANGE_PASS_STRING.replace("{{code}}",code);
            }else if(type == 2){
                sms = BIND_PHONE_STRING.replace("{{code}}",code);
            }else  if(type == 3){
                sms = BIND_PHONE.replace("{{code}}",code);
            }else{
                return returnErrorMap("参数错误",map);
            }
            int r = SMSSender.sendSms(phone,sms);
            if(r > 0){
                session.setAttribute(SESSION_BIND_KEY_PHONE, code);
                session.setAttribute(SESSION_BING_KEY_DATE, new Date());
                session.setAttribute(SESSION_BIND_IS_SMS, "sms");
                session.setAttribute(SESSION_BIND_SEND_PHONE, phone);
            }else{
                return returnErrorMap("系统错误",map);
            }
            returnData(r, map);
        }else{
            return returnErrorMap("手机格式不正确.",map);
        }
        return map;
    }

    /**
     * 检测短信发送时间间隔,大于1分钟返回true
     * @param session
     * @return
     */
    public boolean canSendSMS(HttpSession session){
        Object o = session.getAttribute(SESSION_BING_KEY_DATE);
        if(o != null && o instanceof Date){
            Date d = (Date)o;
            long old = d.getTime();
            return (new Date().getTime() - old) > (1000*60);
        }
        return true;
    }



    public static void main(String a[]){
       System.out.println(StringUtils.getRadomCode());
    }
    @ApiOperation("第一次绑定手机号，发送验证码")
    @RequestMapping(value = "bindphone/{phone}", method = RequestMethod.GET)
    public Map<String, Object> sendSMS(@PathVariable String phone,
                                       HttpSession session) {
        Map<String, Object> map = getInitMap();
        SysUser sysUser = sysUserService.getSysUserByPhone(phone, false);
        if(null == sysUser){
            map = sendSmsByType(phone, 3, session);
        }else{
            returnErrorMap("手机号已被绑定.", map);
        }
        return map;
    }
}
